//! # 配置刷新模块
//!
//! 提供配置的主动刷新和热更新功能，支持多种刷新策略和触发机制。
//!
//! ## 核心功能
//!
//! * **定时刷新** - 按固定间隔自动刷新配置
//! * **手动刷新** - 支持手动触发配置刷新
//! * **条件刷新** - 基于条件的智能刷新策略
//! * **批量刷新** - 同时刷新多个配置
//! * **增量刷新** - 只刷新变更的配置部分
//! * **刷新回调** - 配置刷新后的自定义处理

use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, SystemTime};

use tokio::sync::{broadcast, RwLock};
use tokio::time::{interval, Interval};
use tracing::{debug, error, info, warn};

use crate::RustCloudConfig;
use super::{
    ConfigClient, ConfigEnvironment, ConfigChangeEvent, ConfigEventType,
    ConfigCache, RemoteConfigFetcher, ConfigClientError, ClientResult,
};

/// 刷新策略
#[derive(Debug, Clone)]
pub enum RefreshStrategy {
    /// 固定间隔刷新
    FixedInterval {
        /// 刷新间隔
        interval: Duration,
    },
    /// 指数退避刷新（失败时逐渐增加间隔）
    ExponentialBackoff {
        /// 初始间隔
        initial_interval: Duration,
        /// 最大间隔
        max_interval: Duration,
        /// 退避倍数
        multiplier: f64,
    },
    /// 基于变更频率的自适应刷新
    Adaptive {
        /// 基础间隔
        base_interval: Duration,
        /// 最小间隔
        min_interval: Duration,
        /// 最大间隔
        max_interval: Duration,
    },
    /// 仅手动刷新
    Manual,
}

impl Default for RefreshStrategy {
    fn default() -> Self {
        Self::FixedInterval {
            interval: Duration::from_secs(30),
        }
    }
}

/// 刷新条件
#[derive(Debug, Clone)]
pub struct RefreshCondition {
    /// 应用名称过滤
    pub applications: Option<Vec<String>>,
    /// 环境过滤
    pub profiles: Option<Vec<String>>,
    /// 标签过滤
    pub labels: Option<Vec<String>>,
    /// 最小刷新间隔
    pub min_interval: Option<Duration>,
    /// 失败重试次数
    pub retry_count: u32,
}

impl Default for RefreshCondition {
    fn default() -> Self {
        Self {
            applications: None,
            profiles: None,
            labels: None,
            min_interval: Some(Duration::from_secs(5)),
            retry_count: 3,
        }
    }
}

/// 刷新结果
#[derive(Debug, Clone)]
pub struct RefreshResult {
    /// 刷新的环境
    pub environment: ConfigEnvironment,
    /// 是否成功
    pub success: bool,
    /// 是否有变更
    pub changed: bool,
    /// 错误信息
    pub error: Option<String>,
    /// 刷新耗时
    pub duration: Duration,
    /// 刷新时间
    pub timestamp: SystemTime,
}

/// 配置刷新器
pub struct ConfigRefresher {
    /// 远程配置获取器
    fetcher: Arc<dyn RemoteConfigFetcher>,
    /// 配置缓存
    cache: Option<Arc<dyn ConfigCache>>,
    /// 刷新策略
    strategy: RefreshStrategy,
    /// 刷新条件
    condition: RefreshCondition,
    /// 监听的环境列表
    environments: Arc<RwLock<Vec<ConfigEnvironment>>>,
    /// 配置版本缓存
    version_cache: Arc<RwLock<HashMap<String, String>>>,
    /// 配置内容缓存
    config_cache: Arc<RwLock<HashMap<String, RustCloudConfig>>>,
    /// 刷新历史
    refresh_history: Arc<RwLock<Vec<RefreshResult>>>,
    /// 事件发送器
    event_sender: broadcast::Sender<ConfigChangeEvent>,
    /// 当前刷新间隔（用于自适应策略）
    current_interval: Arc<RwLock<Duration>>,
    /// 连续失败次数
    failure_count: Arc<RwLock<u32>>,
    /// 是否正在运行
    running: Arc<RwLock<bool>>,
}

impl ConfigRefresher {
    /// 创建新的配置刷新器
    pub fn new(
        fetcher: Arc<dyn RemoteConfigFetcher>,
        cache: Option<Arc<dyn ConfigCache>>,
        strategy: RefreshStrategy,
        condition: RefreshCondition,
        event_sender: broadcast::Sender<ConfigChangeEvent>,
    ) -> Self {
        let initial_interval = match &strategy {
            RefreshStrategy::FixedInterval { interval } => *interval,
            RefreshStrategy::ExponentialBackoff { initial_interval, .. } => *initial_interval,
            RefreshStrategy::Adaptive { base_interval, .. } => *base_interval,
            RefreshStrategy::Manual => Duration::from_secs(60), // 默认值，不会实际使用
        };

        Self {
            fetcher,
            cache,
            strategy,
            condition,
            environments: Arc::new(RwLock::new(Vec::new())),
            version_cache: Arc::new(RwLock::new(HashMap::new())),
            config_cache: Arc::new(RwLock::new(HashMap::new())),
            refresh_history: Arc::new(RwLock::new(Vec::new())),
            event_sender,
            current_interval: Arc::new(RwLock::new(initial_interval)),
            failure_count: Arc::new(RwLock::new(0)),
            running: Arc::new(RwLock::new(false)),
        }
    }

    /// 添加刷新环境
    pub async fn add_environment(&self, environment: ConfigEnvironment) {
        let mut environments = self.environments.write().await;
        if !environments.contains(&environment) {
            environments.push(environment.clone());
            info!("🔄 添加刷新环境: {}:{}:{}", 
                environment.application, environment.profile, environment.label);
        }
    }

    /// 移除刷新环境
    pub async fn remove_environment(&self, environment: &ConfigEnvironment) {
        let mut environments = self.environments.write().await;
        environments.retain(|env| env != environment);
        info!("🗑️ 移除刷新环境: {}:{}:{}", 
            environment.application, environment.profile, environment.label);
    }

    /// 开始自动刷新
    pub async fn start(&self) -> ClientResult<()> {
        let mut running = self.running.write().await;
        if *running {
            debug!("⚠️ 刷新器已在运行中");
            return Ok(());
        }
        *running = true;
        drop(running);

        info!("🚀 启动配置刷新器");

        match &self.strategy {
            RefreshStrategy::FixedInterval { interval } => {
                self.start_fixed_interval_refresh(*interval).await;
            }
            RefreshStrategy::ExponentialBackoff { 
                initial_interval, 
                max_interval, 
                multiplier 
            } => {
                self.start_exponential_backoff_refresh(*initial_interval, *max_interval, *multiplier).await;
            }
            RefreshStrategy::Adaptive { 
                base_interval, 
                min_interval, 
                max_interval 
            } => {
                self.start_adaptive_refresh(*base_interval, *min_interval, *max_interval).await;
            }
            RefreshStrategy::Manual => {
                info!("📝 手动刷新模式，不启动自动刷新");
            }
        }

        Ok(())
    }

    /// 停止自动刷新
    pub async fn stop(&self) {
        let mut running = self.running.write().await;
        *running = false;
        info!("🛑 停止配置刷新器");
    }

    /// 手动刷新所有配置
    pub async fn refresh_all(&self) -> ClientResult<Vec<RefreshResult>> {
        info!("🔄 手动刷新所有配置");
        
        let environments = self.environments.read().await.clone();
        let mut results = Vec::new();

        for environment in environments {
            if self.should_refresh(&environment).await {
                let result = self.refresh_single(&environment).await;
                results.push(result);
            }
        }

        info!("✅ 手动刷新完成，处理了 {} 个配置", results.len());
        Ok(results)
    }

    /// 刷新指定配置
    pub async fn refresh_environment(&self, environment: &ConfigEnvironment) -> ClientResult<RefreshResult> {
        info!("🔄 刷新指定配置: {}:{}:{}", 
            environment.application, environment.profile, environment.label);
        
        let result = self.refresh_single(environment).await;
        
        if result.success {
            info!("✅ 配置刷新成功");
        } else {
            warn!("❌ 配置刷新失败: {}", result.error.as_deref().unwrap_or("未知错误"));
        }

        Ok(result)
    }

    /// 启动固定间隔刷新
    async fn start_fixed_interval_refresh(&self, refresh_interval: Duration) {
        let environments = self.environments.clone();
        let running = self.running.clone();
        let fetcher = self.fetcher.clone();
        let cache = self.cache.clone();
        let version_cache = self.version_cache.clone();
        let config_cache = self.config_cache.clone();
        let refresh_history = self.refresh_history.clone();
        let event_sender = self.event_sender.clone();
        let condition = self.condition.clone();

        tokio::spawn(async move {
            let mut ticker = interval(refresh_interval);
            debug!("📊 开始固定间隔刷新，间隔: {:?}", refresh_interval);

            loop {
                ticker.tick().await;

                let is_running = *running.read().await;
                if !is_running {
                    debug!("🛑 刷新器已停止，退出刷新任务");
                    break;
                }

                let envs = environments.read().await.clone();
                for environment in envs {
                    if let Err(e) = Self::refresh_single_internal(
                        &environment,
                        &fetcher,
                        &cache,
                        &version_cache,
                        &config_cache,
                        &refresh_history,
                        &event_sender,
                        &condition,
                    ).await {
                        error!("❌ 配置刷新失败 {}:{}:{}: {}", 
                            environment.application, environment.profile, environment.label, e);
                    }
                }
            }
        });
    }

    /// 启动指数退避刷新
    async fn start_exponential_backoff_refresh(
        &self, 
        initial_interval: Duration, 
        max_interval: Duration, 
        multiplier: f64
    ) {
        let environments = self.environments.clone();
        let running = self.running.clone();
        let current_interval = self.current_interval.clone();
        let failure_count = self.failure_count.clone();
        let fetcher = self.fetcher.clone();
        let cache = self.cache.clone();
        let version_cache = self.version_cache.clone();
        let config_cache = self.config_cache.clone();
        let refresh_history = self.refresh_history.clone();
        let event_sender = self.event_sender.clone();
        let condition = self.condition.clone();

        tokio::spawn(async move {
            debug!("📊 开始指数退避刷新，初始间隔: {:?}", initial_interval);

            loop {
                let current_interval_value = *current_interval.read().await;
                tokio::time::sleep(current_interval_value).await;

                let is_running = *running.read().await;
                if !is_running {
                    debug!("🛑 刷新器已停止，退出刷新任务");
                    break;
                }

                let envs = environments.read().await.clone();
                let mut has_failure = false;

                for environment in envs {
                    match Self::refresh_single_internal(
                        &environment,
                        &fetcher,
                        &cache,
                        &version_cache,
                        &config_cache,
                        &refresh_history,
                        &event_sender,
                        &condition,
                    ).await {
                        Ok(_) => {
                            // 刷新成功，重置间隔
                            if *current_interval.read().await != initial_interval {
                                let mut interval = current_interval.write().await;
                                *interval = initial_interval;
                                let mut count = failure_count.write().await;
                                *count = 0;
                                debug!("✅ 刷新成功，重置间隔为: {:?}", initial_interval);
                            }
                        }
                        Err(e) => {
                            error!("❌ 配置刷新失败 {}:{}:{}: {}", 
                                environment.application, environment.profile, environment.label, e);
                            has_failure = true;
                        }
                    }
                }

                // 如果有失败，增加间隔
                if has_failure {
                    let mut interval = current_interval.write().await;
                    let mut count = failure_count.write().await;
                    *count += 1;
                    
                    let new_interval = Duration::from_secs_f64(
                        interval.as_secs_f64() * multiplier
                    );
                    
                    if new_interval <= max_interval {
                        *interval = new_interval;
                        debug!("⏰ 刷新失败，增加间隔为: {:?}", new_interval);
                    } else {
                        *interval = max_interval;
                        debug!("⏰ 刷新失败，使用最大间隔: {:?}", max_interval);
                    }
                }
            }
        });
    }

    /// 启动自适应刷新
    async fn start_adaptive_refresh(
        &self,
        base_interval: Duration,
        min_interval: Duration,
        max_interval: Duration,
    ) {
        // TODO: 实现基于变更频率的自适应刷新逻辑
        warn!("⚠️ 自适应刷新策略暂未完全实现，使用固定间隔");
        self.start_fixed_interval_refresh(base_interval).await;
    }

    /// 检查是否应该刷新
    async fn should_refresh(&self, environment: &ConfigEnvironment) -> bool {
        // 检查应用过滤
        if let Some(apps) = &self.condition.applications {
            if !apps.contains(&environment.application) {
                return false;
            }
        }

        // 检查环境过滤
        if let Some(profiles) = &self.condition.profiles {
            if !profiles.contains(&environment.profile) {
                return false;
            }
        }

        // 检查标签过滤
        if let Some(labels) = &self.condition.labels {
            if !labels.contains(&environment.label) {
                return false;
            }
        }

        // 检查最小间隔
        if let Some(min_interval) = self.condition.min_interval {
            let env_key = format!("{}:{}:{}", 
                environment.application, environment.profile, environment.label);
            
            let history = self.refresh_history.read().await;
            if let Some(last_result) = history.iter().rev().find(|r| {
                format!("{}:{}:{}", r.environment.application, r.environment.profile, r.environment.label) == env_key
            }) {
                if last_result.timestamp.elapsed().unwrap_or_default() < min_interval {
                    debug!("⏰ 距离上次刷新时间不足，跳过: {}", env_key);
                    return false;
                }
            }
        }

        true
    }

    /// 刷新单个配置
    async fn refresh_single(&self, environment: &ConfigEnvironment) -> RefreshResult {
        Self::refresh_single_internal(
            environment,
            &self.fetcher,
            &self.cache,
            &self.version_cache,
            &self.config_cache,
            &self.refresh_history,
            &self.event_sender,
            &self.condition,
        ).await.unwrap_or_else(|e| RefreshResult {
            environment: environment.clone(),
            success: false,
            changed: false,
            error: Some(e.to_string()),
            duration: Duration::from_millis(0),
            timestamp: SystemTime::now(),
        })
    }

    /// 内部刷新单个配置实现
    async fn refresh_single_internal(
        environment: &ConfigEnvironment,
        fetcher: &Arc<dyn RemoteConfigFetcher>,
        cache: &Option<Arc<dyn ConfigCache>>,
        version_cache: &Arc<RwLock<HashMap<String, String>>>,
        config_cache: &Arc<RwLock<HashMap<String, RustCloudConfig>>>,
        refresh_history: &Arc<RwLock<Vec<RefreshResult>>>,
        event_sender: &broadcast::Sender<ConfigChangeEvent>,
        condition: &RefreshCondition,
    ) -> ClientResult<RefreshResult> {
        let start_time = SystemTime::now();
        let env_key = format!("{}:{}:{}", 
            environment.application, environment.profile, environment.label);

        debug!("🔄 开始刷新配置: {}", env_key);

        // 获取当前版本
        let current_version = fetcher.get_version(environment).await?;
        
        // 检查版本是否变更
        let version_changed = {
            let cache = version_cache.read().await;
            cache.get(&env_key).map(|v| v != &current_version).unwrap_or(true)
        };

        let mut result = RefreshResult {
            environment: environment.clone(),
            success: true,
            changed: false,
            error: None,
            duration: Duration::from_millis(0),
            timestamp: SystemTime::now(),
        };

        if version_changed {
            debug!("📝 检测到版本变更，获取新配置: {}", env_key);
            
            // 获取新配置
            let new_config = fetcher.fetch_config(environment).await?;
            
            // 获取旧配置
            let old_config = {
                let cache = config_cache.read().await;
                cache.get(&env_key).cloned()
            };

            // 更新版本缓存
            {
                let mut cache = version_cache.write().await;
                cache.insert(env_key.clone(), current_version);
            }

            // 更新配置缓存
            {
                let mut cache = config_cache.write().await;
                cache.insert(env_key.clone(), new_config.clone());
            }

            // 更新外部缓存
            if let Some(external_cache) = cache {
                if let Err(e) = external_cache.put_config(environment, &new_config).await {
                    warn!("⚠️ 更新外部缓存失败: {}", e);
                }
            }

            // 发送变更事件
            let event = ConfigChangeEvent {
                event_type: if old_config.is_some() { 
                    ConfigEventType::Updated 
                } else { 
                    ConfigEventType::Created 
                },
                environment: environment.clone(),
                new_config: Some(new_config),
                old_config,
                timestamp: SystemTime::now(),
            };

            if let Err(e) = event_sender.send(event) {
                warn!("⚠️ 发送配置变更事件失败: {}", e);
            } else {
                debug!("📢 配置变更事件已发送: {}", env_key);
            }

            result.changed = true;
        } else {
            debug!("📋 配置版本未变更: {}", env_key);
        }

        result.duration = start_time.elapsed().unwrap_or_default();

        // 记录刷新历史
        {
            let mut history = refresh_history.write().await;
            history.push(result.clone());
            
            // 保持历史记录在合理范围内
            if history.len() > 1000 {
                history.drain(0..500); // 保留最近500条记录
            }
        }

        debug!("✅ 配置刷新完成: {} (耗时: {:?})", env_key, result.duration);
        Ok(result)
    }

    /// 获取刷新历史
    pub async fn get_refresh_history(&self, limit: Option<usize>) -> Vec<RefreshResult> {
        let history = self.refresh_history.read().await;
        match limit {
            Some(n) => history.iter().rev().take(n).cloned().collect(),
            None => history.clone(),
        }
    }

    /// 获取刷新统计
    pub async fn get_refresh_stats(&self) -> RefreshStats {
        let history = self.refresh_history.read().await;
        let total_refreshes = history.len();
        let successful_refreshes = history.iter().filter(|r| r.success).count();
        let changed_refreshes = history.iter().filter(|r| r.changed).count();
        
        let avg_duration = if !history.is_empty() {
            let total_duration: Duration = history.iter().map(|r| r.duration).sum();
            total_duration / total_refreshes as u32
        } else {
            Duration::from_millis(0)
        };

        RefreshStats {
            total_refreshes,
            successful_refreshes,
            changed_refreshes,
            success_rate: if total_refreshes > 0 {
                successful_refreshes as f64 / total_refreshes as f64
            } else {
                0.0
            },
            change_rate: if total_refreshes > 0 {
                changed_refreshes as f64 / total_refreshes as f64
            } else {
                0.0
            },
            average_duration: avg_duration,
            current_interval: *self.current_interval.read().await,
            is_running: *self.running.read().await,
        }
    }
}

/// 刷新统计信息
#[derive(Debug, Clone)]
pub struct RefreshStats {
    /// 总刷新次数
    pub total_refreshes: usize,
    /// 成功刷新次数
    pub successful_refreshes: usize,
    /// 变更刷新次数
    pub changed_refreshes: usize,
    /// 成功率
    pub success_rate: f64,
    /// 变更率
    pub change_rate: f64,
    /// 平均耗时
    pub average_duration: Duration,
    /// 当前刷新间隔
    pub current_interval: Duration,
    /// 是否正在运行
    pub is_running: bool,
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
    use tokio::sync::broadcast;

    // Mock远程配置获取器
    struct MockRefreshFetcher {
        version_counter: AtomicUsize,
        should_fail: AtomicBool,
    }

    impl MockRefreshFetcher {
        fn new() -> Self {
            Self {
                version_counter: AtomicUsize::new(1),
                should_fail: AtomicBool::new(false),
            }
        }

        fn set_should_fail(&self, should_fail: bool) {
            self.should_fail.store(should_fail, Ordering::Relaxed);
        }

        fn increment_version(&self) {
            self.version_counter.fetch_add(1, Ordering::Relaxed);
        }
    }

    #[async_trait::async_trait]
    impl RemoteConfigFetcher for MockRefreshFetcher {
        async fn fetch_config(&self, _environment: &ConfigEnvironment) -> ClientResult<RustCloudConfig> {
            if self.should_fail.load(Ordering::Relaxed) {
                return Err(ConfigClientError::ServerConnectionError("Mock failure".to_string()));
            }
            Ok(RustCloudConfig::default())
        }

        async fn health_check(&self) -> ClientResult<bool> {
            Ok(!self.should_fail.load(Ordering::Relaxed))
        }

        async fn get_version(&self, _environment: &ConfigEnvironment) -> ClientResult<String> {
            if self.should_fail.load(Ordering::Relaxed) {
                return Err(ConfigClientError::ServerConnectionError("Mock failure".to_string()));
            }
            let version = self.version_counter.load(Ordering::Relaxed);
            Ok(format!("v{}", version))
        }
    }

    #[tokio::test]
    async fn test_manual_refresh() {
        let fetcher = Arc::new(MockRefreshFetcher::new());
        let (sender, _) = broadcast::channel(10);
        let strategy = RefreshStrategy::Manual;
        let condition = RefreshCondition::default();

        let refresher = ConfigRefresher::new(fetcher.clone(), None, strategy, condition, sender);

        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "main".to_string(),
            version: None,
            state: None,
        };

        refresher.add_environment(environment.clone()).await;

        // 手动刷新
        let result = refresher.refresh_environment(&environment).await.unwrap();
        assert!(result.success);
        assert!(result.changed); // 第一次刷新应该有变更

        // 再次刷新，版本未变更
        let result = refresher.refresh_environment(&environment).await.unwrap();
        assert!(result.success);
        assert!(!result.changed); // 版本未变更，应该没有变更
    }

    #[tokio::test]
    async fn test_version_change_detection() {
        let fetcher = Arc::new(MockRefreshFetcher::new());
        let (sender, _) = broadcast::channel(10);
        let strategy = RefreshStrategy::Manual;
        let condition = RefreshCondition::default();

        let refresher = ConfigRefresher::new(fetcher.clone(), None, strategy, condition, sender);

        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "main".to_string(),
            version: None,
            state: None,
        };

        refresher.add_environment(environment.clone()).await;

        // 第一次刷新
        let result = refresher.refresh_environment(&environment).await.unwrap();
        assert!(result.success);
        assert!(result.changed);

        // 版本未变更
        let result = refresher.refresh_environment(&environment).await.unwrap();
        assert!(result.success);
        assert!(!result.changed);

        // 更新版本
        fetcher.increment_version();
        let result = refresher.refresh_environment(&environment).await.unwrap();
        assert!(result.success);
        assert!(result.changed); // 版本变更，应该有变更
    }

    #[tokio::test]
    async fn test_refresh_stats() {
        let fetcher = Arc::new(MockRefreshFetcher::new());
        let (sender, _) = broadcast::channel(10);
        let strategy = RefreshStrategy::Manual;
        let condition = RefreshCondition::default();

        let refresher = ConfigRefresher::new(fetcher.clone(), None, strategy, condition, sender);

        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "main".to_string(),
            version: None,
            state: None,
        };

        refresher.add_environment(environment.clone()).await;

        // 执行几次刷新
        for _ in 0..3 {
            let _ = refresher.refresh_environment(&environment).await;
            fetcher.increment_version();
        }

        // 模拟一次失败
        fetcher.set_should_fail(true);
        let _ = refresher.refresh_environment(&environment).await;

        let stats = refresher.get_refresh_stats().await;
        assert_eq!(stats.total_refreshes, 4);
        assert_eq!(stats.successful_refreshes, 3);
        assert!(stats.success_rate > 0.0);
    }
}